using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using COM = System.Runtime.InteropServices.ComTypes;
//http://msdn.microsoft.com/en-us/library/ms221627.aspx
//http://www.koders.com/csharp/fid20F77D1184902DBE03A81BA6E908DC3926C68DE7.aspx?s=IDIspatch
//http://www.koders.com/csharp/fidC97DE36885E7B0C3DDFC4CCEA3E644E0EF6C666A.aspx?s=IDispatch
namespace Tridion.Gateway
{
    [StructLayout(LayoutKind.Sequential)]
    struct SafeArray 
    {
        public ushort dimensions; 
        public ushort features; 
        public uint elementSize; 
        public uint locks; 
        public IntPtr dataPtr; 
        public uint elementCount; 
        public int lowerBound;  
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct VARIANT
    {
        [FieldOffset(0)]
        public short variantType;

        [FieldOffset(8)]
        public int intValue;
    }

    [ComVisible(false)]
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("00000000-0000-0000-C000-000000000046")]
    public interface IUnknown
    {
        IntPtr QueryInterface(ref Guid riid);

        [PreserveSig]
        UInt32 AddRef();

        [PreserveSig]
        UInt32 Release();
        
    }
    
    [
     ComImport,
     InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
     Guid("00020400-0000-0000-C000-000000000046")
     ]

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")]
    public interface IDispatchForReflection
    {
    }

    [
    ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("00020400-0000-0000-C000-000000000046"),
    ]
    public interface IDispatch
    {
        [PreserveSig]
        int GetTypeInfoCount(out uint pctinfo);

        [PreserveSig]
        int GetTypeInfo(uint iTInfo, int lcid, out IntPtr info);

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
        [PreserveSig]
        int GetIDsOfNames(
            ref Guid iid,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)]
            string[] names,
            uint cNames,
            int lcid,
            [Out]
            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 2)]
            int[] rgDispId);

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate")]
        [PreserveSig]
        int Invoke(
            int dispIdMember,
            ref Guid riid,
            int lcid,
            COM.INVOKEKIND wFlags,
            ref COM.DISPPARAMS pDispParams,
            out object VarResult,
            out COM.EXCEPINFO pExcepInfo,
            out uint puArgErr);
    }

    /// <summary>
    /// Layout of the IDispatch vtable
    /// </summary>
    internal enum IDispatchMethodIndices
    {
        IUnknown_QueryInterface,
        IUnknown_AddRef,
        IUnknown_Release,

        IDispatch_GetTypeInfoCount,
        IDispatch_GetTypeInfo,
        IDispatch_GetIDsOfNames,
        IDispatch_Invoke
    }

}
